package cn.stronglink.esm27.collection.iot.devices.algorithmservice.algorithm;

import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.sun.jna.Native;

import cn.stronglink.esm27.collection.iot.devices.algorithmservice.entity.Point;

public class ParticleLandingAlgorithm implements IAlgorithm {
	protected MathModelAPI api;

	protected Optional<Integer> as; // 婢堆勭毜缁嬪啿鐣炬惔锔肩礉閺佹潙鐎烽敍灞藉絿閸婏拷 1,2,3,4,5,6 娑撳骸銇囧鏃偳旂�规艾瀹抽崣鏍э拷鑹般�冮惃鍕嚠鎼存柨鍙х化锟� 1=A,
									// 2=B, 3=C, 4=D, 5=E, 6=F
	protected Optional<Double> ws, // 閻滎垰顣ㄦ搴拷鐕傜礉娑擄拷閼割剙褰囬崷浼存桨 10m 妤傛ê顦╅惃鍕挬閸у洭顥撻柅鐕傜礉閸楁洑缍卪/s
			wd, // 妞嬪骸鎮滈敍灞藉礋娴ｅ秴瀹�
			gd, // 濮光剝鐓嬪鏂剧秼閸︺劌鐖跺〒鈺�绗呴惃鍕タ鎼达讣绱濋崡鏇氱秴 kg/m3
			h, // 閻戠喖娴樺▔鍕础閻愬湱顬囬崷浼存桨閻ㄥ嫰鐝惔锟�
			dq; // 妫版鐭戦悧鈺傜爱瀵搫瀹抽敍瀹琯/s
	protected Optional<Double> fCurrentTime; // 鐠侊紕鐣� fCurrentTime 閺冨爼妫块悙鍦畱閼煎啫娲挎潪顔肩波缁撅拷 fCurrentTime: 閹碘晜鏆庨弮鍫曟？
												// 鏉╂柨娲栭崐锟� true 鐠侊紕鐣婚幋鎰閿涘畺alse 鐠侊紕鐣绘径杈Е
	protected Optional<double[]> concentrations; // 鐠佸墽鐤嗗ù鎾冲闂冨牆锟借偐娈戦弫鎵矋

	public ParticleLandingAlgorithm() {

		String filePath = GasDispersionAlgorithm.class.getResource("").getPath().replaceFirst("/", "").replaceAll("%20",
				" ") + "MathModel.dll";
		this.api = (MathModelAPI) Native.loadLibrary(filePath, MathModelAPI.class);
	}

	@Override
	public void updateParams(Object[] params) {
		Preconditions.checkNotNull(params);
		Preconditions.checkArgument(params.length >= 6);

		this.as = Optional.of((int) params[0]);
		Preconditions.checkArgument((int) this.as.get() > 0 && (int) this.as.get() < 7,
				"閸欐牕锟界厧绱撶敮锟�,閸欐牕锟借壈瀵栭崶锟� 1閿濓拷6閵嗭拷");
		this.ws = Optional.of((double) params[1]);
		this.wd = Optional.of((double) params[2]);
		this.gd = Optional.of((double) params[3]);
		this.h = Optional.of((double) params[4]);
		this.dq = Optional.of((double) params[5]);
		this.fCurrentTime = Optional.of((double) params[6]);
		this.concentrations = Optional.of((double[]) params[7]);
	}

	@Override
	public Object calc() {
		// 閸掓繂顫愰崠鏍吀缁犳鐨垫担鎻侾I
		int initResult = this.api.Init_API();
		Preconditions.checkArgument(initResult == 1, "閸掓繂顫愰崠鏍с亼鐠愶拷,鏉╂柨娲栭崐锟�:" + initResult);
		// 鐠佸墽鐤嗘０妤冪煈閻椻晜鐭囬梽宥喣侀崹瀣棘閺侊拷
		this.api.SetPsParameters_API((int) as.get(), (double) ws.get(), (double) wd.get(), (double) gd.get(),
				(double) h.get(), (double) dq.get());
		// 鐠佸墽鐤嗙粔顖氬瀻閺冨爼妫块梻鎾閿涘奔绡冮崣顖欎簰娑撳秷顔曠純顔筋劃閸欏倹鏆熼敍宀�鈻兼惔蹇撳敶姒涙顓婚弰锟� 1
		// 缁夋帪绱濋梻鎾鐡掑﹦鐓拋锛勭暬濞嗏剝鏆熺搾濠傤樋閼版妞傜搾濠囨毐閿涘矂妫块梾鏃囩Ш闂�鑳吀缁犳顐奸弫鎷岀Ш鐏忔垼锟芥妞傜搾濠傜毌閵嗭拷
		// dt: 缁夘垰鍨庨弮鍫曟？闂傛挳娈ч敍灞藉礋娴ｅ秶顫梥
//		this.api.SetPsDeltaT_API((double)dt.get());
		// 瀵拷婵膩閹风噦绱濈拋锛勭暬 fCurrentTime 閺冨爼妫块悙鍦畱閼煎啫娲挎潪顔肩波缁撅拷 fCurrentTime: 閹碘晜鏆庨弮鍫曟？
		// 鏉╂柨娲栭崐锟� true 鐠侊紕鐣婚幋鎰閿涘畺alse 鐠侊紕鐣绘径杈Е
		boolean isSuccess = this.api.SimulatePs_API(0);
		Preconditions.checkArgument(isSuccess);

		List<List<Point>> result = new ArrayList<>();
		for (int i = 0; i < this.concentrations.get().length; i++) {
			// 鐠佸墽鐤嗗▽澶愭鐠愩劑鍣洪梼鍫濓拷纭风礉鐠侊紕鐣诲銈嗙焽闂勫秷宸濋柌蹇氬瘱閸ョ鐤嗗鎾跺殠閿涘苯宕熸担宄ゞ/m3 t: 缁涘锟借偐鍤�
			this.api.SetPsThreshold_API(this.concentrations.get()[i]);
			// 閼惧嘲褰囨潪顔肩波缁惧潡銆婇悙鐟版綏閺嶅洦鏆熺紒鍕畱闂�鍨
			int psVerticesLen = this.api.GetPsVerticesLength_API();
			double[] datas = new double[psVerticesLen];
			// 閼惧嘲褰囨潪顔肩波缁惧潡銆婇悙鐟版綏閺嶅洦鏆熺紒鍒恱1,y1,x2,y2,......]
			this.api.GetPsVertices_API(datas);
			List<Point> subPointList = new ArrayList<>();
			for (int j = 0; j < datas.length - 2; j += 3) {
				Point point = new Point();
				point.setX(datas[j]);
				point.setY(datas[j + 1]);
				point.setZ(datas[j + 2]);
				subPointList.add(point);
			}
			result.add(subPointList);
		}
		return result;
	}

}
